﻿using System;
using System.Data;
using System.Data.Common;
using System.Data.OleDb;

namespace Flagwind.Data.Providers
{
	/// <summary>
	/// OleDb 数据访问提供程序类。
	/// </summary>
	public class OleDb : DataProviderBase
	{
		#region 公共属性

		/// <summary>
		/// 当前数据库的类型枚举。
		/// </summary>
		public override DataProviderType ProviderType
		{
			get
			{
				return DataProviderType.UNKNOWN;
			}
		}

		/// <summary>
		/// 获取连接字符串构造类。
		/// </summary>
		public override DbConnectionStringBuilder ConnectionStringBuilder
		{
			get
			{
				return new OleDbConnectionStringBuilder(this.ConnectionString);
			}
		}

		/// <summary>
		/// 获取连接数据库用户的Id。
		/// </summary>
		public override string ConnectionUserId
		{
			get
			{
				if(this.ConnectionStringBuilder.ContainsKey("User ID"))
				{
					return this.ConnectionStringBuilder["User ID"].ToString();
				}
				else
				{
					return "";
				}
			}
		}

		/// <summary>
		/// 获取当前连接字符串中的数据源字符串。
		/// 如果是|DataDirectory|，将返回数据源文件对应的绝对路径。
		/// </summary>
		public string ConnectionDataSource
		{
			get
			{
				if(ConnectionStringBuilder.ContainsKey("Data Source"))
				{
					string path = this.ConnectionStringBuilder["Data Source"].ToString();
					if(path.StartsWith("|DataDirectory|", StringComparison.OrdinalIgnoreCase))
					{
						object obj = AppDomain.CurrentDomain.GetData("DataDirectory");
						if(obj == null)
						{
							throw new InvalidOperationException("当前应用程序域未设置 DataDirectory");
						}
						string dataPath = obj.ToString();
						string fileName = path.Substring("|DataDirectory|".Length);
						string dbFilePath = System.IO.Path.Combine(dataPath, fileName);
						return dbFilePath;
					}
					return path;
				}
				else
				{
					return null;
				}
			}
		}

		#endregion

		#region 获取方法

		public override IDataParameter GetParameter()
		{
			return new OleDbParameter();
		}

		public override IDataParameter GetParameter(string name, DbType type, int size)
		{
			return new OleDbParameter
			{
				ParameterName = name, DbType = type, Size = size
			};
		}

		public override DataTable GetSchema(string collectionName, string[] restrictionValues)
		{
			using(var connection = (OleDbConnection)this.GetConnection())
			{
				connection.Open();
				if(restrictionValues == null && string.IsNullOrEmpty(collectionName))
				{
					return connection.GetSchema();
				}
				else if(restrictionValues == null && !string.IsNullOrEmpty(collectionName))
				{
					return connection.GetSchema(collectionName);
				}
				else
				{
					return connection.GetSchema(collectionName, restrictionValues);
				}
			}
		}

		public override IDbConnection GetConnection(string connectionString)
		{
			this.ConnectionString = connectionString;
			return new OleDbConnection(this.ConnectionString);
		}

		public override IDbDataAdapter GetDataAdapter(IDbCommand command)
		{
			return new OleDbDataAdapter((OleDbCommand)command);
		}

		public override string GetNativeDbTypeName(IDataParameter parameter)
		{
			return ((OleDbParameter)parameter).OleDbType.ToString();
		}

		#endregion
	}
}